package org.wenhuayuan.library.util

import androidx.lifecycle.*
import java.util.concurrent.ConcurrentHashMap

object HiDataBus {
    private val eventMap = ConcurrentHashMap<String, StickyLiveData<*>>()

    /**基于时间名称 订阅、分发消息*/
    /**由于一个livedata 只能发送一种数据类型，所以不同event事件，需要使用不同的livedata实例区分发*/
    fun <T> with (eventName:String):StickyLiveData<T> {
        var liveData = eventMap[eventName]
        if (null == liveData) {
            liveData = StickyLiveData<T>(eventName)
            eventMap[eventName] = liveData
        }

        return liveData as StickyLiveData<T>

    }



    class StickyLiveData<T>(private val eventName: String): LiveData<T>() {
        var mStickyData:T?=null

        fun setStickyData(stickyData:T) {
            mStickyData = stickyData
            setValue(stickyData) // 这个只能在主线程发送使用
        }

        fun postStickyData (stickyData: T) {
            mStickyData = stickyData
            postValue(stickyData)
        }

        // 控制发送的次数 start
        var mVersion = 0
        override fun setValue(value: T) {
            mVersion++
            super.setValue(value)
        }

        override fun postValue(value: T) {
            mVersion++
            super.postValue(value)
        }
        // 控制发送的次数 end

        override fun observe(owner: LifecycleOwner, observer: Observer<in T>) {
            observerSticky(owner, false, observer)
        }

        fun observerSticky(owner:LifecycleOwner, sticky:Boolean, observer:Observer<in T>) {
            // 允许指定注册的观察者是否需要关心粘性事件
            // sticky=true  如果之前存在已经发送的数据，那么这个observer会收到之前的粘性事件消息
            // 改代码存在的目的就是，为了得到（获取）当前宿主的生命周期状态来做处理
            owner.lifecycle.addObserver(object:LifecycleEventObserver{
                // 这里的方法onStateChanged，会根据当前宿主的生命周期状态计算并跟进，且回调方法onStateChanged
                override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) {
                    // 监听宿主发生销毁事件，主动把livedata移除
                    if (event == Lifecycle.Event.ON_DESTROY) {
                        eventMap.remove(eventName)
                    }
                }
            })
            super.observe(owner, StickyObserver(this, sticky, observer))
        }
    }
}

class StickyObserver<T> (
    val stickyLiveData: HiDataBus.StickyLiveData<T>,
    val sticky: Boolean,
    val observer: Observer<in T>
) : Observer<T> {

    private var lastVersion = stickyLiveData.mVersion // 对齐，为了控制粘性事件的分发

    override fun onChanged(t: T) {
        if (lastVersion >= stickyLiveData.mVersion) {
            // 说明stickyLiveData 没有更新的数据需要发送
            if (sticky && stickyLiveData!= null) {
                observer.onChanged(stickyLiveData.mStickyData)
            }
          return
        }

        lastVersion = stickyLiveData.mVersion
        observer.onChanged(t)
    }

}
